package com.nbcio.iot.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.nbcio.common.core.domain.R;
import com.nbcio.iot.domain.entity.IotNodeRedFlow;
import com.nbcio.iot.mapper.IotNodeRedFlowMapper;
import com.nbcio.iot.service.NodeRedService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@Slf4j
@RestController
@RequestMapping("/iot/nodered")
@RequiredArgsConstructor
public class IotNodeRedController {

    private final IotNodeRedFlowMapper flowMapper;
    private final NodeRedService nodeRedService;

    @GetMapping("/flows")
    public R<Page<IotNodeRedFlow>> getFlows(@RequestParam(defaultValue = "1") long pageNum,
                                           @RequestParam(defaultValue = "10") long pageSize,
                                           @RequestParam(required = false) String flowName) {
        LambdaQueryWrapper<IotNodeRedFlow> qw = new LambdaQueryWrapper<>();
        if (flowName != null && !flowName.isEmpty()) {
            qw.like(IotNodeRedFlow::getFlowName, flowName);
        }
        qw.orderByDesc(IotNodeRedFlow::getUpdateTime);
        Page<IotNodeRedFlow> page = flowMapper.selectPage(new Page<>(pageNum, pageSize), qw);
        return R.ok(page);
    }

    @GetMapping("/flows/{id}")
    public R<IotNodeRedFlow> getFlow(@PathVariable("id") Long id) {
        return R.ok(flowMapper.selectById(id));
    }

    @PostMapping("/flows")
    public R<Void> createFlow(@RequestBody IotNodeRedFlow flow) {
        flow.setIsActive(false);
        flow.setIsRunning(false);
        flow.setVersion(1);
        flowMapper.insert(flow);
        return R.ok();
    }

    @PutMapping("/flows")
    public R<Void> updateFlow(@RequestBody IotNodeRedFlow flow) {
        flowMapper.updateById(flow);
        return R.ok();
    }

    @DeleteMapping("/flows/{id}")
    public R<Void> deleteFlow(@PathVariable("id") Long id) {
        // 先停止运行中的 Flow
        nodeRedService.stopFlow(id);
        flowMapper.deleteById(id);
        return R.ok();
    }

    @PostMapping("/flows/{id}/deploy")
    public R<Void> deployFlow(@PathVariable("id") Long id) {
        IotNodeRedFlow flow = flowMapper.selectById(id);
        if (flow == null) {
            return R.fail("Flow 不存在");
        }
        nodeRedService.deployFlow(flow);
        return R.ok();
    }

    @PostMapping("/flows/{id}/stop")
    public R<Void> stopFlow(@PathVariable("id") Long id) {
        nodeRedService.stopFlow(id);
        return R.ok();
    }

    @GetMapping("/flows/{id}/status")
    public R<String> getFlowStatus(@PathVariable("id") Long id) {
        String status = nodeRedService.getFlowStatus(id);
        return R.ok(status);
    }

    @PostMapping("/flows/import")
    public R<Void> importFlow(@RequestBody String flowJson) {
        nodeRedService.importFlow(flowJson);
        return R.ok();
    }

    @GetMapping("/flows/{id}/export")
    public R<String> exportFlow(@PathVariable("id") Long id) {
        String flowJson = nodeRedService.exportFlow(id);
        return R.ok(flowJson);
    }

    @GetMapping("/editor")
    public R<String> getEditorUrl() {
        String editorUrl = nodeRedService.getEditorUrl();
        return R.ok(editorUrl);
    }
}